package com.dy.yunying.biz.controller.sign;

import com.dy.yunying.api.entity.sign.SignTaskConfigDO;
import com.dy.yunying.api.req.sign.SignTaskConfigVO;
import com.dy.yunying.api.req.sign.SignTaskConfigVO.Edit;
import com.dy.yunying.api.req.sign.SignTaskConfigVO.Save;
import com.dy.yunying.biz.service.sign.SignTaskConfigService;
import com.pig4cloud.pig.common.core.util.R;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Title null.java
 * @Package com.dy.yunying.biz.controller.sign
 * @Author 马嘉祺
 * @Date 2021/12/1 9:21
 * @Description
 */
@RestController
@RequestMapping("/taskConfig")
@RequiredArgsConstructor
public class TaskConfigController {

	private final SignTaskConfigService signTaskConfigService;

	/**
	 * 任务记录列表
	 *
	 * @return
	 */
	@GetMapping("/taskConfigList")
	public R<List<SignTaskConfigDO>> taskConfigList(@RequestParam Long activityId) {
		final List<SignTaskConfigDO> taskConfigList = signTaskConfigService.taskConfigList(activityId);
		return R.ok(taskConfigList);
	}

	/**
	 * 保存任务配置信息
	 *
	 * @param task
	 * @return
	 */
	@PostMapping("/saveTaskConfig")
	public R<String> saveTaskConfig(@Validated(Save.class) SignTaskConfigVO task) {

		try {
			// 处理参数
			this.validateSaveTaskConfig(task);
		} catch (IllegalArgumentException e) {
			return R.failed(e.getMessage());
		}

		try {
			Pair<Integer, Integer> pair = signTaskConfigService.saveTaskConfig(task);
			return this.resultString(task, pair);
		} catch (IllegalArgumentException e) {
			return R.failed(e.getMessage());
		}

	}

	// 保存时校验参数
	private void validateSaveTaskConfig(SignTaskConfigVO task) {
		// 校验参数
		if (null != task.getConditionType() && 10 == task.getConditionType()) {
			if (null == task.getConditionRoleRecharge()) {
				throw new IllegalArgumentException("请提供充值金额参数");
			}
		} else {
			task.setConditionRoleRecharge(null);
		}
		if (null != task.getExtraBonusType() && 1 == task.getExtraBonusType()) {
			if (null == task.getExtraBonusNum()) {
				throw new IllegalArgumentException("请提供额外奖励数量");
			}
		} else {
			task.setExtraBonusNum(null);
		}
		final Integer prizeType = task.getPrizeType();
		if (1 == prizeType) {
			this.validateGameGoods(task, Boolean.FALSE);
		} else if (2 == prizeType) {
			this.validateCdk(task, Boolean.FALSE);
		} else if (3 == prizeType) {
			this.validateCurrencyAmount(task, Boolean.FALSE);
		} else {
			throw new IllegalArgumentException("未知的奖品类型");
		}
	}

	/**
	 * 修改任务配置信息
	 *
	 * @param task
	 * @return
	 */
	@PostMapping("/editTaskConfig")
	public R<String> editTaskConfig(@Validated(Edit.class) SignTaskConfigVO task) {

		try {
			// 处理参数
			this.validateEditTaskConfig(task);
		} catch (IllegalArgumentException e) {
			return R.failed(e.getMessage());
		}

		try {
			Pair<Integer, Integer> pair = signTaskConfigService.editTaskConfig(task);
			return this.resultString(task, pair);
		} catch (IllegalArgumentException e) {
			return R.failed(e.getMessage());
		}

	}

	// 编辑时校验参数
	private void validateEditTaskConfig(SignTaskConfigVO task) {
		// 校验参数
		if (null != task.getConditionType() && 10 != task.getConditionType()) {
			task.setConditionRoleRecharge(null);
		}
		if (null != task.getExtraBonusType() && 1 != task.getExtraBonusType()) {
			task.setExtraBonusNum(null);
		}
		final Integer prizeType = task.getPrizeType();
		if (1 == prizeType) {
			this.validateGameGoods(task, Boolean.TRUE);
		} else if (2 == prizeType) {
			this.validateCdk(task, Boolean.TRUE);
		} else if (3 == prizeType) {
			this.validateCurrencyAmount(task, Boolean.TRUE);
		} else {
			throw new IllegalArgumentException("未知的奖品类型");
		}
	}

	private void validateGameGoods(SignTaskConfigVO task, boolean edit) {
		// 礼包唯一码
		Integer giftType = task.getGiftType();
		if (null == giftType) {
			throw new IllegalArgumentException("请选择礼包码类型");
		} else if (1 == giftType) {
			this.validateUniqueGiftBagFile(task, edit);
		} else if (2 == giftType) {
			this.validateUniversalGiftBagCode(task, edit);
		} else {
			throw new IllegalArgumentException("未知的礼包码类型");
		}
		// 处理物品列表
		this.convertTaskGoodsList(task, edit);
	}

	// 校验礼包码参数
	private void validateUniqueGiftBagFile(SignTaskConfigVO task, boolean edit) {
		final MultipartFile giftBagFile = task.getGiftBagFile();
		if (Objects.isNull(giftBagFile)) {
			throw new IllegalArgumentException("请上传礼包码文件");
		}
		if (giftBagFile.isEmpty()) {
			throw new IllegalArgumentException("请提供正确的礼包码文件");
		}
		if (!ObjectUtils.defaultIfNull(giftBagFile.getOriginalFilename(), StringUtils.EMPTY).endsWith(".txt")) {
			throw new IllegalArgumentException("文件类型必须为txt");
		}
		if (giftBagFile.getSize() < 3 || giftBagFile.getSize() > 1048576) {
			throw new IllegalArgumentException("文件大小必须在 3Byte ~ 1M 之间");
		}
	}

	// 校验通用礼包码编码
	private void validateUniversalGiftBagCode(SignTaskConfigVO task, boolean edit) {
		Integer giftAmount = task.getGiftAmount();
		String giftCode = task.getGiftCode();
		if (StringUtils.isBlank(giftCode) || null == giftAmount) {
			throw new IllegalArgumentException("请输入通用礼包码和礼包码数量");
		}
		String regex = "^[A-Za-z0-9]+$";
		if (giftCode.length() < 3 || giftCode.length() > 50 || !giftCode.matches(regex)) {
			throw new IllegalArgumentException("通用礼包码应为3~50个英文大小写或数字组成");
		}
		if (giftAmount < 0 || giftAmount > 9999999) {
			throw new IllegalArgumentException("礼包数量应为0~9999999");
		}
	}

	// 校验物品列表
	private void convertTaskGoodsList(SignTaskConfigVO task, boolean edit) {
		try {
			final Long[] goodsIds = Arrays.stream(task.getGoodsIdArr().split(",")).map(Long::parseLong).toArray(Long[]::new);
			final Integer[] goodsNums = Arrays.stream(task.getGoodsNumArr().split(",")).map(Integer::parseInt).toArray(Integer[]::new);
			if (ArrayUtils.isEmpty(goodsIds)) {
				throw new IllegalArgumentException("请提供正确的物品ID和物品数量");
			}
			if (ArrayUtils.isEmpty(goodsNums) || goodsIds.length != goodsNums.length) {
				throw new IllegalArgumentException("请提供正确的物品ID和物品数量");
			}
			task.setGoodsIds(goodsIds).setGoodsNums(goodsNums);
		} catch (NumberFormatException | NullPointerException e) {
			throw new IllegalArgumentException("请提供正确的物品ID和物品数量", e);
		}
	}

	// 校验代金券
	private void validateCdk(SignTaskConfigVO task, boolean edit) {
		if (StringUtils.isBlank(task.getCdkName())) {
			throw new IllegalArgumentException("请提供代金券名称参数");
		}
		final BigDecimal amount = task.getCdkAmount();
		if (null == amount || amount.compareTo(BigDecimal.ZERO) < 0) {
			throw new IllegalArgumentException("请提供代金券金额，并且代金券金额不能小于0");
		}
		final BigDecimal limitAmount = task.getCdkLimitAmount();
		if (null == limitAmount || limitAmount.compareTo(amount) < 0) {
			throw new IllegalArgumentException("请提供代金券使用门槛，并且使用门槛金额不能小于代金券金额");
		}
		if(null==task.getCdkLimitType()|| (task.getCdkLimitType()<1 || task.getCdkLimitType()>3)){
			throw new IllegalArgumentException("请提供代金券限制类型");
		}
		final Integer expireType = task.getCdkExpireType();
		if (null == expireType) {
			throw new IllegalArgumentException("请提供代金券过期类型");
		} else if (1 == expireType) {
			final Date startTime = task.getCdkStartTime(), endTime = task.getCdkEndTime();
			if (null == startTime || null == endTime || startTime.after(endTime)) {
				throw new IllegalArgumentException("请提供正确代金券固定开始和结束时间，并且结束时间不能小于开始时间");
			}
		} else if (2 == expireType) {
			final Integer expireDays = task.getCdkExpireDays();
			if (null == expireDays || expireDays < 0) {
				throw new IllegalArgumentException("请提供正确的代金券过期天数，并且过期天数不能小于0");
			}
		} else {
			throw new IllegalArgumentException("未知的代金券过期类型");
		}
	}

	// 校验余额
	private void validateCurrencyAmount(SignTaskConfigVO task, boolean edit) {
		final BigDecimal amount = task.getCurrencyAmount();
		if (null == amount || amount.compareTo(BigDecimal.ZERO) < 0) {
			throw new IllegalArgumentException("请提供余额金额，并且金额不能小于0");
		}
		final Integer currencyType = task.getCurrencyType();
		if (null == currencyType) {
			throw new IllegalArgumentException("请提供余额类型");
		} else if (1 == currencyType) {
		} else if (2 == currencyType) {
			final Integer expireType = task.getCurrencyExpireType();
			if (null == expireType) {
				throw new IllegalArgumentException("请提供余额过期类型");
			} else if (1 == expireType) {
				final Date expireTime = task.getCurrencyExpireTime();
				if (null == expireTime) {
					throw new IllegalArgumentException("请提供正确的余额过期时间");
				}
			} else if (2 == expireType) {
				final Integer expireDays = task.getCurrencyExpireDays();
				if (null == expireDays || expireDays < 0) {
					throw new IllegalArgumentException("请提供正确的余额过期天数，并且过期天数不能为空");
				}
			} else {
				throw new IllegalArgumentException("未知的余额过期类型");
			}
		} else {
			throw new IllegalArgumentException("未知的余额类型");
		}
	}

	private R<String> resultString(SignTaskConfigVO task, Pair<Integer, Integer> resultPair) {
		final Integer prizeType = task.getPrizeType(), giftType = task.getGiftType();
		if (1 == prizeType && null != giftType && 1 == giftType) {
			// 礼包唯一码
			return R.ok(String.format("共上传%d个礼包码，其中无效或重复%d个", resultPair.getLeft(), resultPair.getLeft() - resultPair.getRight()));
		} else {
			return R.ok("操作成功");
		}
	}

	/**
	 * 删除任务配置
	 *
	 * @param id
	 * @return
	 */
	@DeleteMapping("/deleteTaskConfig")
	public R<Void> deleteTaskConfig(Long id) {
		try {
			signTaskConfigService.deleteTaskConfigByTaskId(id);
			return R.ok();
		} catch (IllegalArgumentException e) {
			return R.failed(e.getMessage());
		}
	}

}
